﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace Cloak.Mvvm.Navigation
{
	/// <summary>
	/// Describes a scope in which view models are instantiated for pages
	/// </summary>
	[ContractClass(typeof(IPageModelScopeContract))]
	public interface IPageModelScope : IDisposable
	{
		/// <summary>
		/// Resolves an instance of the referenced view model for the page at the specified URI and with the specified parameters
		/// </summary>
		/// <param name="pageUri">The URI of the page for which the view model is resolved</param>
		/// <param name="reference">The reference to the view model associated with the page</param>
		/// <param name="parameters">The parameters available when creating the view model</param>
		/// <returns>An instance of the reference view model</returns>
		ViewModel ResolvePageModel(Uri pageUri, PageModelReference reference, IDictionary<string, string> parameters);

		/// <summary>
		/// Creates an inner scope in the context of this scope
		/// </summary>
		/// <returns>A scope in the context of this scope</returns>
		IPageModelScope BeginScope();
	}

	[ContractClassFor(typeof(IPageModelScope))]
	internal abstract class IPageModelScopeContract : IPageModelScope
	{
		ViewModel IPageModelScope.ResolvePageModel(Uri pageUri, PageModelReference reference, IDictionary<string, string> parameters)
		{
			Contract.Requires(reference != null);
			Contract.Requires(parameters != null);
			Contract.Ensures(Contract.Result<ViewModel>() != null);

			return null;
		}

		IPageModelScope IPageModelScope.BeginScope()
		{
			Contract.Ensures(Contract.Result<IPageModelScope>() != null);

			return null;
		}

		void IDisposable.Dispose()
		{}
	}
}